package com.onpositive.datacollection.editor;

import java.io.RandomAccessFile;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;

import com.caucho.hessian.client.HessianProxyFactory;
import com.onpositive.data.IReadableObjectCollection;
import com.onpositive.data.diskstorage.AbstractObjectCollection;
import com.onpositive.data.serializer.readers.ObjectCollectionReader;
import com.onpositive.data.serializer.readers.RandomAccessFileAccess;
import com.onpositive.datacollection.proxy.IRemoteCollectionProxy;
import com.onpositive.datacollection.proxy.RemoteDataCollection;
import com.onpositive.datamap.core.IDataCollection;
import com.onpositive.datamap.core.IDataProperty;
import com.onpositive.datamap.core.impl.DataCollection;
import com.onpositive.datamap.values.impl.ValueSequence;
import com.onpositive.semantic.model.api.changes.IObjectListener;
import com.onpositive.semantic.model.api.changes.IValueListener;
import com.onpositive.semantic.model.api.changes.ObjectChangeManager;
import com.onpositive.semantic.model.api.meta.BaseMeta;
import com.onpositive.semantic.model.api.meta.IHasMeta;
import com.onpositive.semantic.model.api.meta.MetaAccess;
import com.onpositive.semantic.model.api.property.ValueUtils;
import com.onpositive.semantic.model.api.realm.IRealm;
import com.onpositive.semantic.model.api.realm.IRealmProvider;
import com.onpositive.semantic.model.api.realm.Realm;
import com.onpositive.semantic.model.remote.TransportConfig;
import com.onpositive.semantic.model.remote.TransportRegistry;

public class DataCollectionAcess {

	private static DataCollection tc;
	
	static IRemoteCollectionProxy proxy;
	
	static HashMap<String, RemoteDataCollection>collections=new HashMap<String, RemoteDataCollection>();
	
	static {
		
		final TransportConfig config =TransportRegistry.getTransportConfiguration("dci");
		initProxy(config);
		ObjectChangeManager.addWeakListener(config,new IValueListener<Object>() {

			/**
			 * 
			 */
			private static final long serialVersionUID = 1L;

			@Override
			public void valueChanged(Object oldValue, Object newValue) {
				initProxy(config);
			}
		});
	}

	protected static void initProxy(TransportConfig config) {
		try {
			proxy=(IRemoteCollectionProxy) new HessianProxyFactory(DataCollectionAcess.class.getClassLoader()).create(IRemoteCollectionProxy.class, 
					config.getUrl()+"/datacollections"+"/proxy");

		} catch (MalformedURLException e) {
			//throw new IllegalStateException();
		}
	}
	
	public static RemoteDataCollection getCollection(String id){
		RemoteDataCollection remoteDataCollection = collections.get(id);
		if (remoteDataCollection!=null){
			return remoteDataCollection;
		}
		RemoteDataCollection c=new RemoteDataCollection(id, proxy);
		collections.put(id, c);
		return c;
	}
	static HashSet<IObjectListener>lm=new HashSet<IObjectListener>();
	
	public static void addListener(IObjectListener l){
		lm.add(l);
	}
	public static void removeListener(IObjectListener l){
		lm.remove(l);
	}
	

	public static IDataCollection collection() {
		if (tc == null) {
			try {
				RandomAccessFile file = new RandomAccessFile(
						"C:\\work\\android\\com.onpositive.fighterspedia\\assets\\serialized2.awb",
						"r");
				RandomAccessFileAccess randomAccessFileAccess = new RandomAccessFileAccess(
						file);
				IReadableObjectCollection<?>[] collection = new ObjectCollectionReader().getCollection(randomAccessFileAccess);
				AbstractObjectCollection abstractObjectCollection = (AbstractObjectCollection) collection[0];
				tc = new DataCollection(abstractObjectCollection,null,null);
				for (final IDataProperty p:tc.getProperties()){
					BaseMeta m=(BaseMeta) MetaAccess.getMeta(p).getMeta();
					m.registerService(IRealmProvider.class, new IRealmProvider<Object>() {

						/**
						 * 
						 */
						private static final long serialVersionUID = 1L;

						@SuppressWarnings("unchecked")
						@Override
						public IRealm<Object> getRealm(IHasMeta model,
								Object parentObject, Object object) {
							IRealm<?> realm = tc.getRealm();
							ArrayList<Object>m=new ArrayList<Object>();
							for (Object q:realm.getContents()){
								Object value = p.getValue(q);
								if (value instanceof ValueSequence){
									ValueSequence v=(ValueSequence) value;
									value=v.getParts();
								}
								m.addAll(ValueUtils.toCollection(value));
							}
							return new Realm(m);
						}
					});
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return tc;
	}



	public static void setCollection(IDataCollection collection) {
		tc=(DataCollection) collection;
		for (IObjectListener m:lm){
			IValueListener q=(IValueListener) m;
			q.valueChanged(null, collection);
		}
	}
}
